package com.miao.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miao.common.entity.pojo.Product;
import com.miao.common.entity.pojo.ShopOrder;
import com.miao.shop.dao.OrderDao;
import com.miao.shop.dao.ShopProductDao;
import com.miao.shop.entity.vo.OrderVO;
import com.miao.shop.entity.vo.ProductVO;
import com.miao.shop.entity.vo.StoreVO;
import com.miao.shop.service.OrderService;
import com.miao.shop.service.ShopAddressService;
import com.miao.shop.service.ShopCarService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.math.BigDecimal;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author MiaoWenqing
 * @date 2021-02-04 11:36
 */
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, ShopOrder> implements OrderService {
    @Resource
    OrderDao orderDao;
    @Resource
    ShopProductDao shopProductDao;
    @Resource(name = "myRedisTemplate")
    RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ShopAddressService shopAddressService;

    @Resource
    private ShopCarService shopCarService;

    @Override
    public List<ShopOrder> splitOrder(String id, OrderVO orderVO) {
        /**
         * 订单0-12 13-14 15-19分割
         */
        orderVO.setOrderId(id);
        String idPre = id.substring(0, 13);
        String idSuf = id.substring(15, 20);
        int idNo = Integer.parseInt(id.substring(13, 15));

        List<ShopOrder> orders = new LinkedList<>();
        List<StoreVO> stores = orderVO.getStores();
        Date date = new Date();

        BigDecimal BigPrice = BigDecimal.valueOf(0);

        for (int i = 0; i < stores.size(); i++) {
            ShopOrder order = new ShopOrder();
            Map<String, Object> proInfo = new HashMap<>();

            /**
             * 子单号<10 加 0
             */
            List<ProductVO> products = stores.get(i).getProducts();
            BigDecimal price = BigDecimal.valueOf(0);
            BigDecimal totalPrice = BigDecimal.valueOf(0);
            int count = 0;
            ArrayList<Map> proList = new ArrayList<>();

            for (ProductVO product : products) {
                this.shopCarService.delProduct(product.getProId(),String.valueOf(stores.get(i).getStoreId()),orderVO.getCusId());

                Map<String, Object> proInfo1 = new HashMap<>();
                Product pro = shopProductDao.selectById(product.getProId());
                if (pro.getIsDiscount()) {
                    product.setPrice(pro.getProPrice().subtract(pro.getProCost()));
                } else {
                    product.setPrice(pro.getProPrice());
                }
                product.setProName(pro.getProName());
                product.setProIcon(pro.getProIcon());

                price = this.getPrice(pro);
                count = product.getCount();

                totalPrice = totalPrice.add(this.getTotalPrice(price, count));

                proInfo1.put("proId", pro.getProId());
                proInfo1.put("proName", pro.getProName());
                proInfo1.put("proPrice", pro.getProPrice());
                proInfo1.put("proCount", product.getCount());
                proInfo1.put("proTotalPrice", totalPrice);

                proInfo1.put("proIcon", pro.getProIcon());
                proList.add(proInfo1);
            }

            /**
             * 订单总价
             */
            BigDecimal orderPrice = getOrderPrice(totalPrice);
            BigPrice = BigPrice.add(orderPrice);

            proInfo.put("proList", proList);
            proInfo.put("orderPrice", orderPrice);

            String SidNo = ++idNo < 10 ? "" + 0 + idNo : "" + idNo;
            order.setOrderId(idPre + SidNo + idSuf);
            order.setCusId(orderVO.getCusId());
            order.setAddrId(orderVO.getAddrId());
            order.setStoreId(stores.get(i).getStoreId());
            order.setOrderMoney(orderPrice);
            order.setOrderState(1);
            order.setOrderCreateTime(date);
            order.setProInfo(JSON.toJSONString(proInfo));
            orders.add(order);

        }
        //  orderVO.setFreight(); 运费
        orderVO.setTotal(BigPrice);
/**
 * 大订单存入Redis
 */
        this.redisTemplate.opsForValue().set("order:" + orderVO.getCusId() + ":" + orderVO.getOrderId(), orderVO, 15, TimeUnit.MINUTES);
        return orders;
    }


    /**
     * 通过Id查询单价
     *
     * @param product 商品
     * @return
     */
    @Override
    public BigDecimal getPrice(Product product) {

        if (product.getIsDiscount()) {
            product.setProPrice(product.getProPrice().subtract(BigDecimal.valueOf(product.getProDis())));
        } else {
            product.setProPrice(product.getProPrice());
        }
        return product.getProPrice();
    }

    @Override
    public Integer getCount(ProductVO productVO) {
        return productVO.getCount();

    }

    /**
     * 计算商品总价
     *
     * @param price 单价
     * @param count 数量
     * @return
     */
    @Override
    public BigDecimal getTotalPrice(BigDecimal price, Integer count) {
        return price.multiply(BigDecimal.valueOf(count));
    }


    /**
     * 订单总价
     *
     * @param totals
     * @return
     */
    @Override
    public BigDecimal getOrderPrice(BigDecimal totals) {

        if (totals.intValue() - 99 < 0) {
            return totals.add(BigDecimal.valueOf(10));
        }
        return totals;
    }


    @Override
    public int insertOrder(ShopOrder order) {

        return orderDao.insert(order);
    }

    @Override
    public void orderToRds(ShopOrder order) {
        redisTemplate.opsForValue()
                .set("order:" + order.getOrderId(), order.getProInfo(), 15 * 60, TimeUnit.SECONDS);
    }

    @Override
    public String getProInfo(String oId) {
        ShopOrder shopOrder = orderDao.selectById(oId);
        System.out.println(shopOrder);
        String proInfo = shopOrder.getProInfo();

        return proInfo;
    }


    @Override
    public void delFromRds(String oId) {

        redisTemplate.delete("order:" + oId);
    }


    @Override
    public int updateClose(String oId) {
        return orderDao.updateClose(oId);
    }

    @Override
    public int updateRate(String oId) {
        return orderDao.updateRate(oId);
    }


    @Override
    public int updateReceive(String oId) {
        return orderDao.updateReceive(oId);
    }

    @Override
    public int updatePay(String oId) {
        oId = oId.substring(0, 13) + "__" + oId.substring(15, 20);
        return orderDao.updatePay(oId);
    }

    @Override
    public int updateDeliver(Map deliver) {
        return orderDao.updateDeliver(deliver);
    }


    @Override
    public List<ShopOrder> getMyOrder(int cId) {
        Wrapper<ShopOrder> shopOrderWrapper = new QueryWrapper<ShopOrder>()
                .eq("cus_id",cId)
                .ne("order_state",1);

        List<ShopOrder> shopOrders = orderDao.selectList(shopOrderWrapper);
        return shopOrders;
    }

    @Override
    public List<ShopOrder> getMyOrder(int cId, int state) {
        Map<String, Object> map = new HashMap<>();
        map.put("cus_id", cId);
        map.put("order_state", state);
        List<ShopOrder> shopOrders = orderDao.selectByMap(map);
        return shopOrders;
    }

    /**
     * 获取待付款订单列表
     * @param cId
     * @return
     */
    public List<Object> getUnpay(int cId) {
        Set<String> keys = redisTemplate.keys("order:" + cId + ":*");
        List<Object> orders = new ArrayList<>();


        for (String key : keys) {
            Map<String, Object> map = new HashMap<>();
            map.put("TTL",redisTemplate.opsForValue().getOperations().getExpire(key));
            Object order = redisTemplate.opsForValue().get(key);
            map.put("order",order);
            orders.add(map);

        }
        return orders;
    }

    /**
     * 获取当前待付款订单
     * @param key
     * @return
     */
    public Object getCurrentUnpay(String key) {

        HashMap<String, Object> map = new HashMap<>();
        OrderVO order = (OrderVO) redisTemplate.opsForValue().get(key);
        if (null == order) {
            return null;
        }
        map.put("order", order);
        map.put("TTL", redisTemplate.opsForValue().getOperations().getExpire(key));
        map.put("addr", this.shopAddressService.getById(order.getAddrId()));
        return map;
    }
}
